package com.jsb.shiro;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.jsb.model.Admin;
import com.jsb.model.SysAdminRole;
import com.jsb.model.SysAdminRoleExample;
import com.jsb.model.SysAdminRoleExample.Criteria;
import com.jsb.model.SysMenu;
import com.jsb.model.SysRole;
import com.jsb.model.SysRoleMenu;
import com.jsb.model.SysRoleMenuExample;
import com.jsb.service.AdminService;
import com.jsb.service.SysAdminRoleService;
import com.jsb.service.SysMenuService;
import com.jsb.service.SysRoleMenuService;
import com.jsb.service.SysRoleService;

public class UserRealm extends AuthorizingRealm {
	private static final Logger log = Logger.getLogger(UserRealm.class);

	@Autowired
	private AdminService userService;
	@Autowired
	private SysAdminRoleService sysAdminRoleService;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private SysRoleMenuService sysRoleMenuService;
	@Autowired
	private SysMenuService sysMenuService;

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = (String) authcToken.getPrincipal();
		
		// 校验登录验证码
//		if (RegisterAndLoginController.isValidateCodeLogin(username, false, false)){
//			Session session = UserUtils.getSession();
//			String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
//			if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
//				throw new AuthenticationException("msg:验证码错误, 请重试.");
//			}
//		}
		Admin user = userService.getUserByAccount(username);
		if (user == null) {
			throw new UnknownAccountException();// 没找到帐号
		}
//		byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
		return new SimpleAuthenticationInfo(user.getAccount(), // 用户名
				user.getPassword().toCharArray(), // 密码
				getName() // realm name
		);
		
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		Admin user = userService.getUserByAccount(username);
		SysAdminRoleExample example = new SysAdminRoleExample();
		Criteria criteria = example.createCriteria();
		criteria.andUserIdEqualTo(user.getId());
		if(username.equals("admin")){
			example = null;
		}
		List<SysAdminRole> uroles = sysAdminRoleService
				.selectByExample(example);
		for (SysAdminRole urole : uroles) {
			String id = urole.getRoleId();
			SysRole sysRoleById = sysRoleService.getSysRoleById(id);
			String rolename = null;
			if(null != sysRoleById){
				rolename = sysRoleById.getRole();
			}
			SysRoleMenuExample example2 = new SysRoleMenuExample();
			com.jsb.model.SysRoleMenuExample.Criteria createCriteria = example2.createCriteria();
			createCriteria.andRoleIdEqualTo(id);
			List<SysRoleMenu> rmenus = sysRoleMenuService
					.selectByExample(example2);
			for (SysRoleMenu rmenu : rmenus) {
				String menuId = rmenu.getMenuId();
				SysMenu sysMenuById = sysMenuService.getSysMenuById(menuId);
				Object permission = null;
				if(null != sysMenuById){
					permission = sysMenuById.getPerms();
				}
				if (permission == null
						|| StringUtils.isEmpty(permission.toString())) {
					continue;
				}
				log.info("add permission:"+permission);
				authorizationInfo.addStringPermission(permission.toString());
			}
			if(StringUtils.isNotEmpty(rolename)){
				authorizationInfo.addRole(rolename);
			}
		}
		return authorizationInfo;
	}
	/**
	 * 设定密码校验的Hash算法与迭代次数
	 */
//	@PostConstruct
//	public void initCredentialsMatcher() {
//		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("SHA-1");
//		matcher.setHashIterations(1024);
//		setCredentialsMatcher(matcher);
//	}
	private void setSession(Object key, Object value) {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			if (null != session) {
				session.setAttribute(key, value);
			}
		}
	}
	
	private Session getSession() {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			if (null != session) {
				log.info("getsession id:"+session.getId());
				return session;
			}
		}
		return null;
	}
	
	/**
	 * 授权用户信息
	 */
	public static class Principal implements Serializable {

		private static final long serialVersionUID = 1L;
		
		private String id; // 编号
		private String account; // 登录名
		private String name; // 姓名
		
//		private Map<String, Object> cacheMap;

		public Principal(Admin admin) {
			this.id = admin.getId();
			this.account = admin.getAccount();
			this.name = admin.getName();
		}

		public String getId() {
			return id;
		}

		public String getAccount() {
			return account;
		}

		public String getName() {
			return name;
		}


//		@JsonIgnore
//		public Map<String, Object> getCacheMap() {
//			if (cacheMap==null){
//				cacheMap = new HashMap<String, Object>();
//			}
//			return cacheMap;
//		}

		/**
		 * 获取SESSIONID
		 */
		public String getSessionid() {
			try{
				return (String) UserUtils.getSession().getId();
			}catch (Exception e) {
				return "";
			}
		}
		
		@Override
		public String toString() {
			return id;
		}
		
	}
	
}
